use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::PathBuf;

/// LSP服务器配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LspServerConfig {
    /// 服务器名称
    pub name: String,
    /// 服务器命令
    pub command: String,
    /// 命令参数
    pub args: Vec<String>,
    /// 工作目录
    pub working_directory: Option<PathBuf>,
    /// 环境变量
    pub env: HashMap<String, String>,
    /// 支持的文件扩展名
    pub file_extensions: Vec<String>,
    /// 支持的语言ID
    pub language_ids: Vec<String>,
    /// 初始化选项
    pub initialization_options: Option<serde_json::Value>,
    /// 服务器设置
    pub settings: Option<serde_json::Value>,
    /// 是否启用
    pub enabled: bool,
    /// 自动重启
    pub auto_restart: bool,
    /// 最大重启次数
    pub max_restart_count: u32,
    /// 重启间隔（秒）
    pub restart_interval: u64,
    /// 健康检查间隔（秒）
    pub health_check_interval: u64,
}

impl Default for LspServerConfig {
    fn default() -> Self {
        Self {
            name: String::new(),
            command: String::new(),
            args: Vec::new(),
            working_directory: None,
            env: HashMap::new(),
            file_extensions: Vec::new(),
            language_ids: Vec::new(),
            initialization_options: None,
            settings: None,
            enabled: true,
            auto_restart: true,
            max_restart_count: 3,
            restart_interval: 5,
            health_check_interval: 30,
        }
    }
}

/// LSP管理器配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LspManagerConfig {
    /// 服务器配置列表
    pub servers: HashMap<String, LspServerConfig>,
    /// 全局设置
    pub global_settings: GlobalLspSettings,
}

/// 全局LSP设置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GlobalLspSettings {
    /// 启用诊断
    pub enable_diagnostics: bool,
    /// 启用代码补全
    pub enable_completion: bool,
    /// 启用悬停提示
    pub enable_hover: bool,
    /// 启用定义跳转
    pub enable_definition: bool,
    /// 启用引用查找
    pub enable_references: bool,
    /// 启用文档符号
    pub enable_symbols: bool,
    /// 启用代码格式化
    pub enable_formatting: bool,
    /// 最大补全项数量
    pub max_completion_items: usize,
    /// 诊断更新延迟（毫秒）
    pub diagnostic_delay_ms: u64,
    /// 启用增量同步
    pub incremental_sync: bool,
    /// 日志级别
    pub log_level: String,
    /// 最大并发服务器数量
    pub max_concurrent_servers: usize,
    /// 服务器启动超时（秒）
    pub server_startup_timeout: u64,
    /// 请求超时（毫秒）
    pub request_timeout_ms: u64,
}

impl Default for GlobalLspSettings {
    fn default() -> Self {
        Self {
            enable_diagnostics: true,
            enable_completion: true,
            enable_hover: true,
            enable_definition: true,
            enable_references: true,
            enable_symbols: true,
            enable_formatting: true,
            max_completion_items: 100,
            diagnostic_delay_ms: 500,
            incremental_sync: true,
            log_level: "info".to_string(),
            max_concurrent_servers: 10,
            server_startup_timeout: 30,
            request_timeout_ms: 5000,
        }
    }
}

impl Default for LspManagerConfig {
    fn default() -> Self {
        Self {
            servers: create_default_server_configs(),
            global_settings: GlobalLspSettings::default(),
        }
    }
}

/// 创建默认的服务器配置
fn create_default_server_configs() -> HashMap<String, LspServerConfig> {
    let mut servers = HashMap::new();

    // Python (Pylsp)
    servers.insert("python".to_string(), LspServerConfig {
        name: "Python Language Server".to_string(),
        command: "pylsp".to_string(),
        args: vec![],
        file_extensions: vec![".py".to_string(), ".pyi".to_string()],
        language_ids: vec!["python".to_string()],
        ..Default::default()
    });

    // TypeScript/JavaScript (typescript-language-server)
    servers.insert("typescript".to_string(), LspServerConfig {
        name: "TypeScript Language Server".to_string(),
        command: "typescript-language-server".to_string(),
        args: vec!["--stdio".to_string()],
        file_extensions: vec![".ts".to_string(), ".tsx".to_string(), ".js".to_string(), ".jsx".to_string()],
        language_ids: vec!["typescript".to_string(), "javascript".to_string()],
        ..Default::default()
    });

    // Rust (rust-analyzer)
    servers.insert("rust".to_string(), LspServerConfig {
        name: "Rust Analyzer".to_string(),
        command: "rust-analyzer".to_string(),
        args: vec![],
        file_extensions: vec![".rs".to_string()],
        language_ids: vec!["rust".to_string()],
        ..Default::default()
    });

    // Java (jdtls)
    servers.insert("java".to_string(), LspServerConfig {
        name: "Eclipse JDT Language Server".to_string(),
        command: "jdtls".to_string(),
        args: vec![],
        file_extensions: vec![".java".to_string()],
        language_ids: vec!["java".to_string()],
        ..Default::default()
    });

    // C/C++ (clangd)
    servers.insert("cpp".to_string(), LspServerConfig {
        name: "Clangd".to_string(),
        command: "clangd".to_string(),
        args: vec!["--background-index".to_string()],
        file_extensions: vec![".c".to_string(), ".cpp".to_string(), ".cc".to_string(), ".cxx".to_string(), ".h".to_string(), ".hpp".to_string()],
        language_ids: vec!["c".to_string(), "cpp".to_string()],
        ..Default::default()
    });

    // Go (gopls)
    servers.insert("go".to_string(), LspServerConfig {
        name: "Go Language Server".to_string(),
        command: "gopls".to_string(),
        args: vec![],
        file_extensions: vec![".go".to_string()],
        language_ids: vec!["go".to_string()],
        ..Default::default()
    });

    servers
}

impl LspManagerConfig {
    /// 从文件加载配置
    pub fn load_from_file(path: &PathBuf) -> Result<Self, Box<dyn std::error::Error>> {
        let content = std::fs::read_to_string(path)?;
        let config: LspManagerConfig = serde_json::from_str(&content)?;
        Ok(config)
    }

    /// 保存配置到文件
    pub fn save_to_file(&self, path: &PathBuf) -> Result<(), Box<dyn std::error::Error>> {
        let content = serde_json::to_string_pretty(self)?;
        std::fs::write(path, content)?;
        Ok(())
    }

    /// 根据文件扩展名获取服务器配置
    pub fn get_server_for_extension(&self, extension: &str) -> Option<&LspServerConfig> {
        self.servers.values().find(|config| {
            config.enabled && config.file_extensions.contains(&extension.to_string())
        })
    }

    /// 根据语言ID获取服务器配置
    pub fn get_server_for_language(&self, language_id: &str) -> Option<&LspServerConfig> {
        self.servers.values().find(|config| {
            config.enabled && config.language_ids.contains(&language_id.to_string())
        })
    }

    /// 获取所有启用的服务器
    pub fn get_enabled_servers(&self) -> Vec<(&String, &LspServerConfig)> {
        self.servers.iter().filter(|(_, config)| config.enabled).collect()
    }
}
